Passed
Push — master ( 9f3888...a1f273 )
by EMP
01:17
created

main.js ➔ addAccountToTable   B

Complexity

Conditions 5

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 26
rs 8.9332
c 0
b 0
f 0
cc 5
1
"use strict";
2
3
sodium.ready.then(function() {
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
4
5
const ae = new AllEars(function(ok) {
1 ignored issue
show
Bug introduced by
The variable AllEars seems to be never declared. If this is a global, consider adding a /** global: AllEars */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
6
	if (ok) {
7
		document.getElementById("txt_skey").style.background = "#466";
8
		document.getElementById("txt_skey").maxLength = "64";
9
	} else {
10
		console.log("Failed to load All-Ears");
11
	}
12
});
13
14
function TabState(cur, max, btnDele, btnUpdt) {
15
	this.cur = cur;
16
	this.max = max;
17
	this.btnDele = btnDele;
18
	this.btnUpdt = btnUpdt;
19
}
20
21
const tabs = [
22
	new TabState(0, 0, false, true), // Inbox
23
	new TabState(0, 0, false, true), // Outbx
24
	new TabState(0, 2, true, false), // Write
25
	new TabState(0, 3, false, false), // Notes
26
	new TabState(0, 3, false, true) // Admin
27
];
28
29
let tab = 0;
30
const TAB_INBOX = 0;
31
const TAB_OUTBX = 1;
0 ignored issues
show
Unused Code introduced by
The constant TAB_OUTBX seems to be never used. Consider removing it.
Loading history...
32
const TAB_WRITE = 2;
33
const TAB_NOTES = 3;
34
const TAB_ADMIN = 4;
35
36
// Helper functions
37
function getCountryName(countryCode) {
38
	const opts = document.getElementById("gatekeeper_country");
39
40
	for (let i = 0; i < opts.length; i++) {
41
		if (opts[i].value === countryCode) {
42
			return opts[i].textContent;
43
		}
44
	}
45
46
	return "Unknown countrycode: " + countryCode;
47
}
48
49
function getCountryFlag(countryCode) {
50
	return sodium.to_string(new Uint8Array([
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
51
		240, 159, 135, 166 + countryCode.codePointAt(0) - 65,
52
		240, 159, 135, 166 + countryCode.codePointAt(1) - 65
53
	]));
54
}
55
56
function getMsgId(num) {
57
	let i;
58
	if (ae.GetExtMsgHeaders(num).toLowerCase().slice(0, 11) === "message-id:") {
59
		i = 0;
60
	} else {
61
		i = ae.GetExtMsgHeaders(num).toLowerCase().indexOf("\nmessage-id:");
62
		if (i < 1) return "ERR";
63
		i++;
64
	}
65
66
	const x = ae.GetExtMsgHeaders(num).slice(i + 11).trim();
67
	if (x[0] !== "<") return "ERR2";
68
	return x.slice(1, x.indexOf(">"));
69
}
70
71
function displayMsg(isInt, num) {
72
	document.getElementById("midright").scroll(0, 0);
73
74
	const ts = isInt? ae.GetIntMsgTime(num) : ae.GetExtMsgTime(num);
75
76
	document.getElementById("btn_reply").disabled = false;
77
	document.getElementById("btn_reply").onclick = function() {
78
		document.getElementById("write_recv").value = isInt? ae.GetIntMsgFrom(num) : ae.GetExtMsgFrom(num);
79
		document.getElementById("write_subj").value = "Re: " + (isInt ? ae.GetIntMsgTitle(num) : ae.GetExtMsgTitle(num));
80
		document.getElementById("write_rply").textContent = (isInt? "" : getMsgId(num));
81
		document.getElementById("btn_write").click();
82
		document.getElementById("div_write_1").hidden = false;
83
		document.getElementById("div_write_2").hidden = true;
84
		document.getElementById("write_body").focus();
85
		for (const opt of document.getElementById("write_from").options) {
86
			if (opt.value === (isInt ? ae.GetIntMsgTo(num) : ae.GetExtMsgTo(num))) {
87
				opt.selected = true;
88
			}
89
		}
90
	};
91
92
	document.getElementById("msg").hidden = false;
93
	document.getElementById("msg").getElementsByTagName("h1")[0].textContent = isInt ? ae.GetIntMsgTitle(num) : ae.GetExtMsgTitle(num);
94
	document.getElementById("msg").getElementsByTagName("pre")[0].textContent = isInt ? ae.GetIntMsgBody(num) : ae.GetExtMsgBody(num);
95
96
	document.getElementById("readmsg_to").textContent = isInt ? ae.GetIntMsgTo(num) : ae.GetExtMsgTo(num);
97
	document.getElementById("readmsg_date").children[0].textContent = new Date(ts * 1000).toISOString().slice(0, 19).replace("T", " ");
98
99
	if (!isInt) {
100
		document.getElementById("readmsg_ip").hidden = false;
101
		document.getElementById("readmsg_country").hidden = false;
102
		document.getElementById("readmsg_tls").hidden = false;
103
		document.getElementById("readmsg_greet").hidden = false;
104
		document.getElementById("readmsg_timing").hidden = false;
105
		document.getElementById("readmsg_envfrom").hidden = false;
106
107
		const cc = ae.GetExtMsgCountry(num);
108
109
		document.getElementById("readmsg_ip").children[0].textContent = ae.GetExtMsgIp(num);
110
		document.getElementById("readmsg_country").textContent = getCountryFlag(cc) + " " + getCountryName(cc);
111
		document.getElementById("readmsg_tls").children[0].textContent = ae.GetExtMsgTLS(num);
112
		document.getElementById("readmsg_greet").children[0].textContent = ae.GetExtMsgGreet(num);
113
		document.getElementById("readmsg_envfrom").textContent = ae.GetExtMsgFrom(num);
114
115
		let flagText = "";
116
		if (!ae.GetExtMsgFlagVPad(num)) flagText += "<abbr title=\"Invalid padding\">PAD</abbr> ";
117
		if (!ae.GetExtMsgFlagVSig(num)) flagText += "<abbr title=\"Invalid signature\">SIG</abbr> ";
118
		if (!ae.GetExtMsgFlagPExt(num)) flagText += "<abbr title=\"The sender did not use the Extended (ESMTP) protocol\">SMTP</abbr> ";
119
		if (!ae.GetExtMsgFlagQuit(num)) flagText += "<abbr title=\"The sender did not issue the required QUIT command\">QUIT</abbr> ";
120
		if (ae.GetExtMsgFlagRare(num)) flagText += "<abbr title=\"The sender issued unusual command(s)\">RARE</abbr> ";
121
		if (ae.GetExtMsgFlagFail(num)) flagText += "<abbr title=\"The sender issued invalid command(s)\">FAIL</abbr> ";
122
		if (ae.GetExtMsgFlagPErr(num)) flagText += "<abbr title=\"The sender violated the protocol\">PROT</abbr> ";
123
		document.getElementById("readmsg_flags").children[0].innerHTML = flagText.trim();
124
	} else {
125
		document.getElementById("readmsg_ip").hidden = true;
126
		document.getElementById("readmsg_country").hidden = true;
127
		document.getElementById("readmsg_tls").hidden = true;
128
		document.getElementById("readmsg_greet").hidden = true;
129
		document.getElementById("readmsg_timing").hidden = true;
130
		document.getElementById("readmsg_envfrom").hidden = true;
131
132
		let symbol = "<span title=\"Invalid level\">&#x26a0;</span>";
133
		if (ae.GetIntMsgFrom(num) === "system") {if (ae.GetIntMsgLevel(num) === 3) symbol = "<span title=\"System\">&#x1f162;</span>";} // S (System)
134
		else if (ae.GetIntMsgLevel(num) === 0) symbol = "<span title=\"Level 0 User\">&#x1f10c;</span>"; // 0
135
		else if (ae.GetIntMsgLevel(num) === 1) symbol = "<span title=\"Level 1 User\">&#x278a;</span>"; // 1
136
		else if (ae.GetIntMsgLevel(num) === 2) symbol = "<span title=\"Level 2 User\">&#x278b;</span>"; // 2
137
		else if (ae.GetIntMsgLevel(num) === 3) symbol = "<span title=\"Administrator\">&#x1f150;</span>"; // A (Admin)
138
		document.getElementById("readmsg_from").innerHTML = symbol + " " + ae.GetIntMsgFrom(num);
139
140
		let flagText = "";
141
		if (!ae.GetIntMsgFlagVPad(num)) flagText += "<abbr title=\"Invalid padding\">PAD</abbr> ";
142
		if (!ae.GetIntMsgFlagVSig(num)) flagText += "<abbr title=\"Invalid signature\">SIG</abbr> ";
143
		document.getElementById("readmsg_flags").children[0].innerHTML = flagText.trim();
144
	}
145
}
146
147
// Interface
148
function addMsg(isInt, i) {
149
	const inbox = document.getElementById("tbl_inbox");
150
	const sent = document.getElementById("tbl_outbx");
151
152
	const isSent = false; //TODO
153
	const table = isSent ? sent : inbox;
154
155
	const row = table.insertRow(-1);
156
	const cellTime = row.insertCell(-1);
157
	const cellSubj = row.insertCell(-1);
158
	const cellSnd1 = row.insertCell(-1);
159
	const cellSnd2 = row.insertCell(-1);
160
161
	const ts = isInt? ae.GetIntMsgTime(i) : ae.GetExtMsgTime(i);
162
	cellTime.setAttribute("data-ts", ts);
163
	cellTime.textContent = new Date(ts * 1000).toISOString().slice(0, 10);
164
165
	cellSubj.textContent = isInt? ae.GetIntMsgTitle(i) : ae.GetExtMsgTitle(i);
166
167
	if (isInt) {
168
		cellSnd1.textContent = ae.GetIntMsgFrom(i);
169
		cellSnd1.className = (ae.GetIntMsgFrom(i).length === 16) ? "mono" : "";
170
	} else {
171
		const from1 = ae.GetExtMsgFrom(i);
172
		const from2 = from1.substring(from1.indexOf("@") + 1);
173
		const cc = ae.GetExtMsgCountry(i);
174
175
		cellSnd1.textContent = from1.substring(0, from1.indexOf("@"));
176
177
		const flag = document.createElement("abbr");
178
		flag.textContent = getCountryFlag(cc);
179
		flag.title = getCountryName(cc);
180
		cellSnd2.appendChild(flag);
181
182
		const fromText = document.createElement("span");
183
		fromText.textContent = " " + from2;
184
		cellSnd2.appendChild(fromText);
185
	}
186
187
//	divDel.innerHTML = "<input class=\"delMsg\" type=\"checkbox\" data-id=\"" + ae.GetIntMsgIdHex(i) + "\">";
188
189
	row.onclick = function() {
190
		displayMsg(isInt, i);
191
	};
192
/*
193
	cellDel.children[0].onchange = function() {
194
		if (!divDel.children[0].checked) {
195
			const checkboxes = elmt.getElementsByTagName("input");
196
			let checked = false;
197
198
			for (let j = 0; j < checkboxes.length; j++) {
199
				if (checkboxes[j].checked) {
200
					checked = true;
201
					break;
202
				}
203
			}
204
205
			if (!checked) {
206
				document.getElementById(isSent ? "btn_sentdel" : "btn_msgdel").hidden = true;
207
				return;
208
			}
209
		}
210
211
		document.getElementById(isSent? "btn_sentdel" : "btn_msgdel").hidden = false;
212
	};
213
*/
214
}
215
216
function getRowsPerPage() {
217
	const tbl = document.getElementById("tbl_inbox");
218
	tbl.innerHTML = "";
219
	const row = tbl.insertRow(-1);
220
	const cell = row.insertCell(-1);
221
	cell.textContent = "0";
222
223
	const rowsPerPage = Math.floor(getComputedStyle(document.getElementById("div_inbox")).height.replace("px", "") / getComputedStyle(document.querySelector("#tbl_inbox > tbody > tr:first-child")).height.replace("px", "")) - 1; // -1 allows space for 'load more'
224
	tbl.innerHTML = "";
225
	return rowsPerPage;
226
}
227
228
function addMessages() {
229
	const rowsPerPage = getRowsPerPage();
230
	let skipMsgs = rowsPerPage * tabs[TAB_INBOX].cur;
231
232
	const maxExt = ae.GetExtMsgCount();
233
	const maxInt = ae.GetIntMsgCount();
234
235
	tabs[TAB_INBOX].max = Math.floor((maxExt + maxInt) / rowsPerPage);
236
237
	let numExt = 0;
238
	let numInt = 0;
239
	let numAdd = 0;
240
241
	while (numAdd < rowsPerPage) {
242
		const tsInt = (numInt < maxInt) ? ae.GetIntMsgTime(numInt) : -1;
243
		const tsExt = (numExt < maxExt) ? ae.GetExtMsgTime(numExt) : -1;
244
		if (tsInt === -1 && tsExt === -1) break;
245
246
		if (tsInt !== -1 && (tsExt === -1 || tsInt > tsExt)) {
247
			if (skipMsgs > 0) skipMsgs--; else {addMsg(true, numInt); numAdd++;}
248
			numInt++;
249
		} else if (tsExt !== -1) {
250
			if (skipMsgs > 0) skipMsgs--; else {addMsg(false, numExt); numAdd++;}
251
			numExt++;
252
		}
253
	}
254
255
	if (ae.GetReadyMsgKilos() < ae.GetTotalMsgKilos()) {
256
		const inbox = document.getElementById("tbl_inbox");
257
		const row = inbox.insertRow(-1);
258
		const cell = row.insertCell(-1);
259
		cell.textContent = "Load more (" + (ae.GetTotalMsgKilos() - ae.GetReadyMsgKilos()) + " KiB left)";
260
261
		row.onclick = function() {
262
			this.onclick = "";
263
264
			ae.Message_Browse(false, function(successBrowse) {
265
				document.getElementById("tbl_inbox").style.opacity = 1;
266
267
				if (successBrowse) {
268
					addMessages();
269
					if (tabs[tab].cur < tabs[tab].max) document.getElementById("btn_rght").disabled = false;
270
				}
271
			});
272
		};
273
	}
274
}
275
276
function addNotes() {
277
	const tbl = document.getElementById("tbd_texts");
278
279
	for (let i = 0; i < ae.GetNoteCount(); i++) {
280
		const row = tbl.insertRow(-1);
281
		let cell;
282
		cell = row.insertCell(-1); cell.textContent = new Date(ae.GetNoteTime(i) * 1000).toISOString().slice(0, 10);
283
		cell = row.insertCell(-1); cell.textContent = ae.GetNoteTitle(i);
284
		cell = row.insertCell(-1); cell.textContent = ""; // Format
285
		cell = row.insertCell(-1); cell.textContent = ""; // Size
286
		cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\">X</button>";
287
	}
288
}
289
290
function updateAddressCounts() {
291
	document.getElementById("limit_normal").textContent = (ae.GetAddressCountNormal() + "/" + ae.GetAddressLimitNormal(ae.GetUserLevel())).padStart(ae.GetAddressLimitNormal(ae.GetUserLevel()) > 9 ? 5 : 1);
292
	document.getElementById("limit_shield").textContent = (ae.GetAddressCountShield() + "/" + ae.GetAddressLimitShield(ae.GetUserLevel())).padStart(ae.GetAddressLimitShield(ae.GetUserLevel()) > 9 ? 5 : 1);
293
	document.getElementById("limit_total").textContent = ((ae.GetAddressCountNormal() + ae.GetAddressCountShield()) + "/" + ae.GetAddrPerUser()).padStart(5);
294
}
295
296
function adjustLevel(pubkey, level, c) {
297
	const fs = document.getElementById("fs_accs");
298
	fs.disabled = true;
299
300
	ae.Account_Update(pubkey, level, function(success) {
301
		fs.disabled = false;
302
303
		if (success) {
304
			c[4].textContent = level;
305
			c[5].children[0].disabled = (level === 3);
306
			c[6].children[0].disabled = (level === 0);
307
		}
308
	});
309
}
310
311
function addAccountToTable(i) {
312
	const tblAccs = document.getElementById("tbd_accs");
313
	const row = tblAccs.insertRow(-1);
314
	let cell;
315
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserPkHex(i);
316
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserSpace(i);
317
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserNAddr(i);
318
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserSAddr(i);
319
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserLevel(i);
320
321
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">+</button>";
322
	cell.children[0].onclick = function() {const c = this.parentElement.parentElement.cells; adjustLevel(c[0].textContent, parseInt(c[4].textContent) + 1, c);};
323
	cell.children[0].disabled = (ae.Admin_GetUserLevel(i) === 3);
324
325
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">&minus;</button>";
326
	cell.children[0].onclick = function() {const c = this.parentElement.parentElement.cells; adjustLevel(c[0].textContent, parseInt(c[4].textContent) - 1, c);};
327
	cell.children[0].disabled = (ae.Admin_GetUserLevel(i) === 0);
328
329
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">X</button>";
330
	cell.children[0].onclick = function() {
331
		const tr = this.parentElement.parentElement;
332
		ae.Account_Delete(tr.cells[0].textContent, function(success) {
0 ignored issues
show
Unused Code introduced by
The parameter success is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
333
			tr.remove();
334
		});
335
	};
336
}
337
338
function reloadAccount() {
339
	// Limits
340
	const tblLimits = document.getElementById("tbl_limits");
341
	for (let i = 0; i < 4; i++) {
342
		tblLimits.rows[i].cells[1].children[0].value = ae.GetStorageLimit(i) + 1;
343
		tblLimits.rows[i].cells[2].children[0].value = ae.GetAddressLimitNormal(i);
344
		tblLimits.rows[i].cells[3].children[0].value = ae.GetAddressLimitShield(i);
345
	}
346
347
	// Accounts
348
	const tblAccs = document.getElementById("tbd_accs");
349
350
	// All: Our account
351
	const row = tblAccs.insertRow(-1);
352
	let cell;
353
	cell = row.insertCell(-1); cell.textContent = ae.GetUserPkHex();
354
	cell = row.insertCell(-1); cell.textContent = Math.round(ae.GetTotalMsgKilos() / 1024);
355
	cell = row.insertCell(-1); cell.textContent = ae.GetAddressCountNormal();
356
	cell = row.insertCell(-1); cell.textContent = ae.GetAddressCountShield();
357
	cell = row.insertCell(-1); cell.textContent = ae.GetUserLevel();
358
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\" disabled=\"disabled\">+</button>";
359
	cell = row.insertCell(-1); cell.innerHTML = "<button id=\"btn_downme\" type=\"button\" autocomplete=\"off\" disabled=\"disabled\">&minus;</button>";
360
	cell = row.insertCell(-1); cell.innerHTML = "<button id=\"btn_killme\" type=\"button\" autocomplete=\"off\" disabled=\"disabled\">X</button>";
361
362
	// Admin: Other accounts
363
	if (ae.IsUserAdmin()) {
364
		for (let i = 0; i < ae.Admin_GetUserCount(); i++) {
365
			addAccountToTable(i);
366
		}
367
	}
368
369
	document.getElementById("txt_reg").disabled = !ae.IsUserAdmin();
370
	document.getElementById("btn_reg").disabled = !ae.IsUserAdmin();
371
372
	// Contacts
373
	for (let i = 0; i < ae.GetContactCount(); i++) {
374
		addContact(
375
			ae.GetContactMail(i),
376
			ae.GetContactName(i),
377
			ae.GetContactNote(i)
378
		);
379
	}
380
381
	// Addresses
382
	for (let i = 0; i < ae.GetAddressCount(); i++) {
383
		addAddress(i);
384
	}
385
386
	updateAddressCounts();
387
}
388
389 View Code Duplication
function deleteAddress(addr) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
390
	let btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
391
	for (let i = 0; i < btns.length; i++) btns[i].disabled = true;
392
393
	let addressToDelete = -1;
394
395
	for (let i = 0; i < ae.GetAddressCount(); i++) {
396
		if (addr === ae.GetAddress(i)) {
397
			addressToDelete = i;
398
			break;
399
		}
400
	}
401
402
	if (addressToDelete === -1) return;
403
404
	ae.Address_Delete(addressToDelete, function(success) {
405
		if (success) {
406
			document.getElementById("tbl_addrs").deleteRow(addressToDelete);
407
			document.getElementById("write_from").remove(addressToDelete);
408
			updateAddressCounts();
409
410
			if (ae.GetAddressCountNormal() < ae.GetAddressLimitNormal(ae.GetUserLevel())) document.getElementById("btn_address_create_normal").disabled = false;
411
			if (ae.GetAddressCountShield() < ae.GetAddressLimitShield(ae.GetUserLevel())) document.getElementById("btn_address_create_shield").disabled = false;
412
413
			ae.Private_Update(function(success2) {
414
				if (!success2) console.log("Failed to update the Private field");
415
416
				btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
417
				for (let i = 0; i < btns.length; i++) btns[i].disabled = false;
418
			});
419
		} else {
420
			console.log("Failed to delete address");
421
422
			btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
423
			for (let i = 0; i < btns.length; i++) btns[i].disabled = false;
424
		}
425
	});
426
}
427
428 View Code Duplication
function shieldMix(addr) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
429
	let newAddr = "";
430
431
	for (let i = 0; i < 16; i++) {
432
		switch (addr.charAt(i)) {
433
			case '1':
434
				newAddr += "1iIlL".charAt(Math.floor(Math.random() * 5));
435
				break;
436
			case '0':
437
				newAddr += "0oO".charAt(Math.floor(Math.random() * 3));
438
				break;
439
			case 'w':
440
				newAddr += "VvWw".charAt(Math.floor(Math.random() * 4));
441
				break;
442
			default:
443
				newAddr += (Math.random() > 0.5) ? addr.charAt(i) : addr.charAt(i).toUpperCase();
444
		}
445
	}
446
447
	return newAddr;
448
}
449
450
function addAddress(num) {
451
	const addrTable = document.getElementById("tbl_addrs");
452
	const row = addrTable.insertRow(-1);
453
	const cellAddr = row.insertCell(-1);
454
	const cellChk1 = row.insertCell(-1);
455
	const cellChk2 = row.insertCell(-1);
456
	const cellChk3 = row.insertCell(-1);
457
	const cellBtnD = row.insertCell(-1);
458
459
	cellAddr.textContent = ae.GetAddress(num);
460
	cellAddr.onclick = function() {
461
		if (cellAddr.textContent.length === 16)
462
			navigator.clipboard.writeText(shieldMix(cellAddr.textContent) + "@" + ae.GetDomainEml());
1 ignored issue
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
463
		else
464
			navigator.clipboard.writeText(cellAddr.textContent + "@" + ae.GetDomainEml());
465
	};
466
467
	cellChk1.innerHTML = ae.GetAddressAccExt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
468
	cellChk2.innerHTML = ae.GetAddressAccInt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
469
	cellChk3.innerHTML = ae.GetAddressUse_Gk(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
470
471
	cellBtnD.innerHTML = "<button type=\"button\">X</button>";
472
	cellBtnD.onclick = function() {deleteAddress(cellAddr.textContent);};
473
474
	const opt = document.createElement("option");
475
	opt.value = cellAddr.textContent;
476
	opt.textContent = cellAddr.textContent + "@" + ae.GetDomainEml();
477
	document.getElementById("write_from").appendChild(opt);
478
}
479
480
document.getElementById("btn_dele").onclick = function() {
481
	this.blur();
482
483
	if (tab === TAB_WRITE) {
484
		tabs[tab].cur = 0;
485
		updateTab();
486
487
		document.getElementById("write_recv").value = "";
488
		document.getElementById("write_subj").value = "";
489
		document.getElementById("write_body").value = "";
490
491
		document.getElementById("write_recv").focus();
492
	}
493
};
494
495
document.getElementById("btn_updt").onclick = function() {
496
	const btn = this;
497
	btn.disabled = true;
498
	btn.blur();
499
500
	if (tab === TAB_INBOX) {
501
		document.getElementById("tbl_inbox").style.opacity = 0.5;
502
503
		ae.Message_Browse(true, function(successBrowse) {
504
			document.getElementById("tbl_inbox").style.opacity = 1;
505
506
			if (successBrowse) {
507
				addMessages();
508
				addNotes();
509
				btn.disabled = false;
510
			} else {
511
				console.log("Failed to refresh");
512
				btn.disabled = false;
513
			}
514
		});
515
	}
516
};
517
518
function addContact(mail, name, note) {
519
	const tbl = document.getElementById("tbl_ctact");
520
	const row = tbl.insertRow(-1);
521
	const cellMail = row.insertCell(-1);
522
	const cellName = row.insertCell(-1);
523
	const cellNote = row.insertCell(-1);
524
	const cellBtnD = row.insertCell(-1);
525
526
	cellMail.textContent = mail;
527
	cellName.textContent = name;
528
	cellNote.textContent = note;
529
	cellBtnD.innerHTML = "<button type=\"button\">X</button>";
530
531
	cellMail.contentEditable = true;
532
	cellName.contentEditable = true;
533
	cellNote.contentEditable = true;
534
535
	cellBtnD.onclick = function() {row.remove();};
536
}
537
538
document.getElementById("btn_newcontact").onclick = function() {
539
	addContact("", "", "");
540
};
541
542
document.getElementById("btn_savecontacts").onclick = function() {
543
	while (ae.GetContactCount() > 0) {
544
		ae.DeleteContact(0);
545
	}
546
547
	for (const row of document.getElementById("tbl_ctact").rows) {
548
		ae.AddContact(row.cells[0].textContent, row.cells[1].textContent, row.cells[2].textContent);
549
	}
550
551
	const btn = this;
552
	btn.disabled = true;
553
554
	ae.Private_Update(function(success) {
555
		btn.disabled = false;
556
557
		if (!success) {
558
			console.log("Failed contacts update");
559
		}
560
	});
561
};
562
563
function updateTab() {
564
	switch (tab) {
565
		case TAB_INBOX:
566
			addMessages();
567
		break;
568
569
		case TAB_WRITE:
570
			switch (tabs[tab].cur) {
571
				case 0: // Write
572
					document.getElementById("div_write_1").hidden = false;
573
					document.getElementById("div_write_2").hidden = true;
574
					document.getElementById("write_body").focus();
575
				break;
576
577
				case 1: // Verify
578
					ae.Address_Lookup(document.getElementById("write_recv").value, function(pk) {
579
						if (pk) {
580
							document.getElementById("div_write_1").hidden = true;
581
							document.getElementById("div_write_2").hidden = false;
582
583
							document.getElementById("write2_from").textContent = document.getElementById("write_from").value + "@" + ae.GetDomainEml();
584
							document.getElementById("write2_recv").textContent = document.getElementById("write_recv").value;
585
							document.getElementById("write2_pkey").textContent = sodium.to_hex(pk);
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
586
587
							document.getElementById("write2_subj").textContent = document.getElementById("write_subj").value;
588
							document.getElementById("write2_rply").textContent = document.getElementById("write_rply").textContent;
589
							document.getElementById("write2_body").textContent = document.getElementById("write_body").value;
590
						} else {
591
							console.log("Failed lookup");
592
						}
593
					});
594
				break;
595
596
				case 2: // Send
597
					ae.Message_Create(
598
						document.getElementById("write_subj").value,
599
						document.getElementById("write_body").value,
600
						document.getElementById("write_from").value,
601
						document.getElementById("write_recv").value,
602
						document.getElementById("write_rply").textContent,
603
						(document.getElementById("write2_recv").textContent.indexOf("@") > 0) ? null : sodium.from_hex(document.getElementById("write2_pkey").textContent),
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
604
						function(success) {
605
							if (success) {
606
								console.log("Sent ok");
607
							} else {
608
								console.log("Failed sending");
609
							}
610
						}
611
					);
612
				break;
613
			}
614
		break;
615
616
		case TAB_NOTES:
617
			for (let i = 0; i <= tabs[tab].max; i++) {
618
				document.getElementById("div_notes").children[i].hidden = (i !== tabs[tab].cur);
619
			}
620
		break;
621
622
		case TAB_ADMIN:
623
			for (let i = 0; i <= tabs[tab].max; i++) {
624
				document.getElementById("div_admin").children[i].hidden = (i !== tabs[tab].cur);
625
			}
626
		break;
627
	}
628
629
	document.getElementById("btn_left").disabled = (tabs[tab].cur === 0);
630
	document.getElementById("btn_rght").disabled = (tabs[tab].cur === tabs[tab].max);
631
}
632
633
document.getElementById("btn_left").onclick = function() {
634
	tabs[tab].cur--;
635
	if (tabs[tab].cur === 0) this.disabled = true;
636
	if (tabs[tab].cur < tabs[tab].max) document.getElementById("btn_rght").disabled = false;
637
	updateTab();
638
	this.blur();
639
};
640
641
document.getElementById("btn_rght").onclick = function() {
642
	tabs[tab].cur++;
643
	if (tabs[tab].cur === tabs[tab].max) this.disabled = true;
644
	document.getElementById("btn_left").disabled = false;
645
	updateTab();
646
	this.blur();
647
};
648
649
const buttons = document.querySelector("#main1 > .top").getElementsByTagName("button");
650
for (let i = 0; i < buttons.length; i++) {
651
	buttons[i].onclick = function() {
652
		tab = i;
653
654
		for (let j = 0; j < buttons.length; j++) {
655
			document.querySelector("#main1 > .mid").children[j].hidden = (tab !== j);
656
			buttons[j].disabled = (tab === j);
657
		}
658
659
		document.getElementById("btn_left").disabled = (tabs[tab].cur === 0);
0 ignored issues
show
Bug introduced by
The variable tab is changed as part of the for loop for example by i on line 652. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
660
		document.getElementById("btn_rght").disabled = (tabs[tab].cur === tabs[tab].max);
661
		document.getElementById("btn_dele").disabled = !tabs[tab].btnDele;
662
		document.getElementById("btn_updt").disabled = !tabs[tab].btnUpdt;
663
	};
664
}
665
666
function addressCreate(addr) {
667
	const btnN = document.getElementById("btn_address_create_normal");
668
	const btnS = document.getElementById("btn_address_create_shield");
669
	btnN.disabled = true;
670
	btnS.disabled = true;
671
672
	ae.Address_Create(addr, function(success1) {
673
		if (success1) {
674
			ae.Private_Update(function(success2) {
675
				addAddress(ae.GetAddressCount() - 1);
676
				if (addr !== "SHIELD") document.getElementById("txt_address_create_normal").value = "";
677
				updateAddressCounts();
678
679
				if (!success2) console.log("Failed to update the Private field");
680
681
				if (ae.GetAddressCountNormal() < ae.GetAddressLimitNormal(ae.GetUserLevel())) btnN.disabled = false;
682
				if (ae.GetAddressCountShield() < ae.GetAddressLimitShield(ae.GetUserLevel())) btnS.disabled = false;
683
			});
684
		} else {
685
			console.log("Failed to add address");
686
687
			if (ae.GetAddressCountNormal() < ae.GetAddressLimitNormal(ae.GetUserLevel())) btnN.disabled = false;
688
			if (ae.GetAddressCountShield() < ae.GetAddressLimitShield(ae.GetUserLevel())) btnS.disabled = false;
689
		}
690
	});
691
}
692
693
document.getElementById("btn_address_create_normal").onclick = function() {
694
	if (ae.GetAddressCountNormal() >= ae.GetAddressLimitNormal(ae.GetUserLevel())) return;
695
696
	const txtNewAddr = document.getElementById("txt_address_create_normal");
697
	if (!txtNewAddr.reportValidity()) return;
698
699
	addressCreate(txtNewAddr.value);
700
};
701
702
document.getElementById("btn_address_create_shield").onclick = function() {
703
	if (ae.GetAddressCountShield() >= ae.GetAddressLimitShield(ae.GetUserLevel())) return;
704
705
	addressCreate("SHIELD");
706
};
707
708
document.getElementById("btn_reg").onclick = function() {
709
	const btn = document.getElementById("btn_reg");
710
	const txt = document.getElementById("txt_reg");
711
	if (!txt.reportValidity()) return;
712
	btn.disabled = true;
713
714
	ae.Account_Create(txt.value, function(success) {
715
		if (success) {
716
			addAccountToTable(ae.Admin_GetUserCount() - 1);
717
			txt.value = "";
718
		}
719
720
		btn.disabled = false;
721
	});
722
};
723
724
document.getElementById("chk_downme").onclick = function() {document.getElementById("btn_downme").disabled = !this.checked;};
725
document.getElementById("chk_killme").onclick = function() {document.getElementById("btn_killme").disabled = !this.checked;};
726
727
document.getElementById("btn_notepad_savesep").onclick = function() {
728
	const np = document.getElementById("txt_notepad");
729
	np.disabled = true;
730
731
	ae.Message_StoreT("title", np.value, false, function(success) {
732
		if (success) {
733
			np.value = "";
734
			addNotes();
735
		}
736
737
		console.log("Failed to add text");
738
		np.disabled = false;
739
	});
740
};
741
742
document.getElementById("txt_skey").onkeyup = function(event) {
743
	if (event.key === "Enter") {
744
		event.preventDefault();
745
		document.getElementById("btn_enter").click();
746
	}
747
};
748
749
document.getElementById("btn_enter").onclick = function() {
750
	const txtSkey = document.getElementById("txt_skey");
751
	if (!txtSkey.reportValidity()) return;
752
753
	const btn = this;
754
	btn.disabled = true;
755
	document.getElementById("txt_skey").style.background = "#233";
756
757
	ae.SetKeys(txtSkey.value, function(successSetKeys) {
758
		if (successSetKeys) {
759
			ae.Account_Browse(0, function(successBrowse) {
760
				if (successBrowse) {
761
					txtSkey.value = "";
762
763
					reloadAccount();
764
					document.getElementById("div_begin").hidden = true;
765
					document.getElementById("div_main").style.display = "grid";
766
767
					document.getElementById("btn_updt").click();
768
				} else {
769
					console.log("Failed to enter");
770
					btn.disabled = false;
771
					document.getElementById("txt_skey").style.background = "#466";
772
					txtSkey.focus();
773
				}
774
			});
775
		} else {
776
			console.log("Invalid format for key");
777
			btn.disabled = false;
778
			document.getElementById("txt_skey").style.background = "#466";
779
			txtSkey.focus();
780
		}
781
	});
782
};
783
784
});
785